package cn.iocoder.yudao.module.system.service.mail;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.controller.admin.mail.vo.log.MailLogPageReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO;
import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailLogDO;
import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO;
import cn.iocoder.yudao.module.system.dal.mysql.mail.MailLogMapper;
import cn.iocoder.yudao.module.system.enums.mail.MailSendStatusEnum;
import cn.iocoder.yudao.module.system.framework.sms.config.SmsCodeProperties;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.bouncycastle.crypto.Wrapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Objects;

import static cn.hutool.core.exceptions.ExceptionUtil.getRootCauseMessage;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SMS_CODE_EXPIRED;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
/**
 * 邮件日志 Service 实现类
 *
 * @author wangjingyi
 * @since 2022-03-21
 */
@Service
@Validated
public class MailLogServiceImpl implements MailLogService {
    @Resource
    private SmsCodeProperties smsCodeProperties;
    @Resource
    private MailLogMapper mailLogMapper;

    @Override
    public PageResult<MailLogDO> getMailLogPage(MailLogPageReqVO pageVO) {
        return mailLogMapper.selectPage(pageVO);
    }

    @Override
    public MailLogDO getMailLog(Long id) {
        return mailLogMapper.selectById(id);
    }

    @Override
    public Long createMailLog(Long userId, Integer userType, String toMail,
                              MailAccountDO account, MailTemplateDO template,
                              String templateContent, Map<String, Object> templateParams, Boolean isSend,Integer scene) {
        MailLogDO.MailLogDOBuilder logDOBuilder = MailLogDO.builder();
        // 根据是否要发送，设置状态
        logDOBuilder.sendStatus(Objects.equals(isSend, true) ? MailSendStatusEnum.INIT.getStatus()
                : MailSendStatusEnum.IGNORE.getStatus())
                // 用户信息
                .userId(userId).userType(userType).toMail(toMail)
                .accountId(account.getId()).fromMail(account.getMail())
                // 模板相关字段
                .templateId(template.getId()).templateCode(template.getCode()).templateNickname(template.getNickname())
                .templateTitle(template.getTitle()).templateContent(templateContent).templateParams(templateParams)
                .used(0)
                .scene(scene);
        // 插入数据库
        MailLogDO logDO = logDOBuilder.build();
        mailLogMapper.insert(logDO);
        return logDO.getId();
    }

    @Override
    public void updateMailSendResult(Long logId, String messageId, Exception exception) {
        // 1. 成功
        if (exception == null) {
            mailLogMapper.updateById(new MailLogDO().setId(logId).setSendTime(LocalDateTime.now())
                    .setSendStatus(MailSendStatusEnum.SUCCESS.getStatus()).setSendMessageId(messageId));
            return;
        }
        // 2. 失败
        mailLogMapper.updateById(new MailLogDO().setId(logId).setSendTime(LocalDateTime.now())
                .setSendStatus(MailSendStatusEnum.FAILURE.getStatus()).setSendException(getRootCauseMessage(exception)));

    }

    @Resource
    private ObjectMapper objectMapper;
    @Override
    public boolean CheckCode(String email, String code,Integer scene) {

        // 查询最近一条记录
        QueryWrapper<MailLogDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("to_mail", email) // 根据邮箱查询
                .eq("scene",scene)
                .orderByDesc("create_time") // 按创建时间降序
                .last("LIMIT 1"); // 只取最近一条记录

        MailLogDO mailLog = mailLogMapper.selectOne(queryWrapper); // 使用 queryWrapper 查询

        // 如果没有找到记录


        if (mailLog == null) {
            throw exception(SMS_CODE_NOT_FOUND);
        }

        if (mailLog.getUsed()==1) {
            throw exception(SMS_CODE_USED);
        }

        if (LocalDateTimeUtil.between(mailLog.getCreateTime(), LocalDateTime.now()).toMillis()
                >=smsCodeProperties.getExpireTimes().toMillis() ) { // 验证码已过期
            throw exception(SMS_CODE_EXPIRED);
        }


        // 解析 template_params 中的 code
        try {
            // 获取 JSON 字符串
            Map templateParams = mailLog.getTemplateParams(); // 假设 template_params 是 JSON 字符串

            String storedCode = (String) templateParams.get("code");
            // 校验传入的 code 和存储的 code 是否一致
            if (code.equals(storedCode)) {
                System.out.println("验证码校验成功");
                return true;
            } else {
                System.out.println("验证码错误");
                return false;
            }
        } catch (Exception e) {
            System.out.println("解析 template_params 失败: " + e.getMessage());
            return false;
        }
    }

    @Override
    public boolean userMailCode(String email, String code, Integer scene) {
        // 查询最近一条记录
        QueryWrapper<MailLogDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("to_mail", email) // 根据邮箱查询
                .eq("scene", scene) // 根据场景查询
                .orderByDesc("create_time") // 按创建时间降序
                .last("LIMIT 1"); // 只取最近一条记录

        // 查询数据库，获取 MailLogDO 对象
        MailLogDO mailLog = mailLogMapper.selectOne(queryWrapper);

        // 更新记录的 used 字段为 1
        mailLog.setUsed(1); // 假设 used 字段是 Integer 类型
        int updatedRows = mailLogMapper.updateById(mailLog);

        // 判断更新是否成功
        return updatedRows > 0;
    }


}
